import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;

import static java.lang.System.err;
import static java.lang.System.out;

public class ColWhiskers {

    private static final int SEARCH_DEPTH = 12;

    public static void main(String[] args) {
        out.println("Meow and welcome dearest player.");
        out.println("I'm Colonel Whiskers and I can offer you a nice game of"
                  + " checkers.");
        out.println("It would please me if you write your moves as: 11 - 15.");
        out.println();

        boolean blackIsHuman = true;
        boolean whiteIsHuman = false;
        boolean hasFileName = false;
        String fileName = null;
        if (args.length > 0) {
            if (args[0].equalsIgnoreCase("h")) {
                blackIsHuman = true;
                whiteIsHuman = false;
            } else if (args[0].equalsIgnoreCase("c")) {
                blackIsHuman = false;
                whiteIsHuman = true;
            } else {
                fileName = args[0];
                hasFileName = true;
            }
        }
        if ((args.length > 1) && (!hasFileName)) {
            if (args[1].equalsIgnoreCase("h")) {
                whiteIsHuman = true;
            } else if (args[1].equalsIgnoreCase("c")) {
                whiteIsHuman = false;
            } else {
                fileName = args[1];
                hasFileName = true;
            }
        }
        if ((args.length > 2) && (!hasFileName)) {
            fileName = args[2];
        }

        Board board = null;
        if (fileName != null) {
            try {
                board = loadBoard(fileName);
            } catch (IOException e) {
                err.println("Couldn't load board from filename " + fileName);
                e.printStackTrace();
                System.exit(1);
            }
            if (board == null) {
                err.println("Couldn't parse board from filename " + fileName);
                System.exit(1);
            }

            if (!board.isSane()) {
                out.println("You have tried to load a board that violates the"
                            + " rules of the game. Exiting.");
                System.exit(1);
            }
        } else {
            board = new Board();
        }

        Player black;
        Player white;
        if (blackIsHuman) {
            black = new HumanPlayer(true);
        } else {
            //black = new MiniMax(true, new EvalMaterialOnly(), SEARCH_DEPTH);
            //black = new NegaMax(true, new EvalMaterialOnlyNeg(), SEARCH_DEPTH);
            //black = new ABMiniMax(true, new EvalMaterialOnly(), SEARCH_DEPTH);
            //black = new ABMiniMaxDrawFix(true, new EvalMaterialOnly(), SEARCH_DEPTH);
            //black = new QIterABMiniMaxDrawFix(true, new NewEval(), SEARCH_DEPTH);
            black = new QABMiniMaxDrawFix(true, new NewEval(), SEARCH_DEPTH);
        }
        if (whiteIsHuman) {
            white = new HumanPlayer(false);
        } else {
            //white = new MiniMax(false, new EvalMaterialOnly(), SEARCH_DEPTH);
            //white = new NegaMax(false, new EvalMaterialOnlyNeg(), SEARCH_DEPTH);
            //white = new ABMiniMax(false, new EvalMaterialOnly(), SEARCH_DEPTH);
            //white = new ABMiniMaxDrawFix(false, new EvalMaterialOnly(), SEARCH_DEPTH);
            //white = new QIterABMiniMaxDrawFix(false, new NewEval(), SEARCH_DEPTH);
            white = new QABMiniMaxDrawFix(false, new NewEval(), SEARCH_DEPTH);
        }

        GameEngine.runGame(black, white, board);
    }

    public static Board loadBoard(String fileName)
        throws FileNotFoundException, IOException
    {
        if (fileName.endsWith(".wdp")) {
            return loadWdp(fileName);
        } else {
            return loadCwb(fileName);
        }
    }

    public static Board loadCwb(String fileName)
        throws FileNotFoundException, IOException
    {
        ArrayList<String> l = readFile(fileName);
        String[] lines = l.toArray(new String[l.size()]);

        return Board.parseCwb(lines);
    }

    public static Board loadWdp(String fileName)
        throws FileNotFoundException, IOException
    {
        ArrayList<String> lines = readFile(fileName);

        return Board.parseWdp(lines.get(0).trim());
    }

    public static ArrayList<String> readFile(String fileName)
        throws FileNotFoundException, IOException
    {
        ArrayList<String> lines = new ArrayList<String>();
        FileReader in = new FileReader(fileName);
        BufferedReader input = new BufferedReader(in);
        String line = input.readLine();
        while (line != null) {
            lines.add(line);
            line = input.readLine();
        }
        input.close();
        in.close();

        return lines;
    }
}
